home *** CD-ROM | disk | FTP | other *** search
/ SGI Hot Mix 17 / Hot Mix 17.iso / HM17_SGI / research / lib / cw_colorsel.pro < prev    next >
Text File  |  1997-07-08  |  10KB  |  389 lines

  1. ; $Id: cw_colorsel.pro,v 1.8 1997/01/15 03:11:50 ali Exp $
  2. ;
  3. ; Copyright (c) 1992-1997, Research Systems, Inc.  All rights reserved.
  4. ;    Unauthorized reproduction prohibited.
  5. ;+
  6. ; NAME:
  7. ;    CW_COLORSEL
  8. ;
  9. ; PURPOSE:
  10. ;    CW_COLORSEL is a compound widget that displays all the colors
  11. ;    in the current colormap and allows the user to select the color
  12. ;    indices via the mouse or with sliders.
  13. ;
  14. ; CATEGORY:
  15. ;    Compund widgets.
  16. ;
  17. ; CALLING SEQUENCE:
  18. ;     widget = CW_COLORSEL(Parent)
  19. ;
  20. ; INPUTS:
  21. ;    Parent:     The ID of the parent widget.
  22. ;
  23. ; KEYWORD PARAMETERS:
  24. ;    FRAME:     If set, a frame is drawn around the widget.
  25. ;    UVALUE:     The user value for the widget.
  26. ;    XOFFSET: The X offset position
  27. ;    YOFFSET: The Y offset position
  28. ;
  29. ; OUTPUTS:
  30. ;    The ID of the created widget is returned.
  31. ;
  32. ; SIDE EFFECTS:
  33. ;    This widget generates event structures containing a field named
  34. ;    VALUE, which contains the colormap index selected by the user.
  35. ;
  36. ; PROCEDURE:
  37. ;    The COLORSEL widget displays all the colors in the current
  38. ;    colormap in a 16x16 (320x320 pixels) grid. To select a color
  39. ;    index, the user moves the mouse pointer over the desired
  40. ;    color square and presses any mouse button. Alternatively, the
  41. ;    color index can be selected by moving one of the three sliders
  42. ;    provided around the grid.
  43. ;
  44. ;    WIDGET_CONTROL, SET_VALUE=index can be used to set the current
  45. ;        color index.
  46. ;
  47. ;    WIDGET_CONTROL, SET_VALUE=-1 informs the widget to initialize
  48. ;        itself and redraw. It should be called when any of the
  49. ;        following happen:
  50. ;            - The widget needs redrawing.
  51. ;            - The brightest or darkest color has changed. 
  52. ;
  53. ;    WIDGET_CONTROL, GET_VALUE=var can be used to retrieve the
  54. ;        current color index.
  55. ;
  56. ; MODIFICATION HISTORY:
  57. ;    March 30, 1992, AB
  58. ;        Removed the relevant code from XPALETTE.PRO and modified
  59. ;        it to create this reusable widget cluster.
  60. ;    September 4, 1992, SR
  61. ;        Fixed a bug where the value of the xslider was calculated
  62. ;        as negative and WIDGET_CONTROL, SET_VALUE failed.
  63. ;    7 April 1993, AB, Removed state caching.
  64. ;    October 20, 1993, KDB 
  65. ;        Changed return value in function CSEL_GET_VALUE
  66. ;        from state.cur_idx to ret
  67. ;    23 May 1994, AB
  68. ;        Added NOTIFY_REALIZE routine to eliminate the need
  69. ;        to call "WIDGET_CONTROL, SET_VALUE=-1" when the widget
  70. ;        is realized.
  71. ;-
  72.  
  73. pro CSEL_SETSLIDERS, state, type, cur_x, cur_y, idx
  74. ; Set the three position sliders according to the supplied values.
  75. ; Move the mark to the new location.
  76. ; entry:
  77. ;    type - Controls operation of procedure. Can have the following
  78. ;        values:
  79. ;        0 - Set all three sliders from IDX. state.x and state.y
  80. ;            are updated.
  81. ;        1 - Set Row and Column sliders from IDX. Update
  82. ;            state.x and state_y.
  83. ;        2 - Set Column and Index sliders from CUR_X and CUR_Y.
  84. ;        3 - Set Row and Index sliders from CUR_X and CUR_Y.
  85.  
  86.   change_x = 0
  87.   change_y = 0
  88.   change_idx = 0
  89.   nc = !D.table_size
  90.  
  91.   if (type lt 2) then begin        ; From IDX
  92.     if (idx ge nc) then idx = nc -1
  93.     if (type eq 0) then change_idx = 1    ; Update slider to match
  94.     ; Calculate current Y and see if slider value needs changing
  95.     tmp = idx / 16
  96.     if (idx ne cur_y) then begin
  97.       cur_y = tmp
  98.       change_y = 1
  99.     endif
  100.     ; Calculate current X and see if slider value needs changing
  101.     tmp = idx - (cur_y * 16)
  102.     if (tmp GE 0) AND (tmp ne cur_x) then begin
  103.       cur_x = tmp
  104.       change_x = 1
  105.     endif
  106.   endif else begin            ; From CUR_X and CUR_Y
  107.     if (type eq 2) then begin
  108.       tmp = cur_x
  109.       while (((cur_y * 16) + tmp) ge nc) do tmp = tmp - 1
  110.       if (tmp ne cur_x) then begin
  111.         cur_x = tmp
  112.         change_x = 1
  113.       endif
  114.     endif else begin
  115.       tmp = cur_y
  116.       while (((tmp * 16) + cur_x) ge nc) do tmp = tmp - 1
  117.       if (tmp ne cur_y) then begin
  118.         cur_y = tmp
  119.         change_y = 1
  120.       endif
  121.     endelse
  122.     IDX = (cur_y * 16B) + cur_x
  123.     change_idx = 1
  124.   endelse
  125.  
  126.   if (change_x) then WIDGET_CONTROL, set_value=cur_x, state.column
  127.   if (change_y) then WIDGET_CONTROL, set_value=cur_y, state.row
  128.   if (change_idx) then WIDGET_CONTROL, set_value=idx, state.by_index
  129.   state.x = cur_x
  130.   state.y = cur_y
  131.   CSEL_MVMARK, state, idx
  132.  
  133. end
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140.  
  141. function CSEL_NEW_COLORS, state
  142. ; Choose the best foreground and background colors for the current
  143. ; color maps. Returns 1 if the colors changed, 0 otherwise.
  144.  
  145.   res = 0
  146.   luminance = ct_luminance(dark=dark_col, bright=bright_col)
  147.  
  148.   if (bright_col ne state.bright_idx) then begin
  149.     state.bright_idx = bright_col
  150.     res = 1
  151.   endif
  152.  
  153.   if (dark_col ne state.dark_idx) then begin
  154.     state.dark_idx = dark_col
  155.     res = 1
  156.   endif
  157.  
  158.   if (res ne 0) then begin
  159.     marker = bytarr(20, 20) + state.dark_idx
  160.     marker[2, 2] = bytarr(16, 16) + state.bright_idx
  161.     marker[4, 4] = bytarr(12, 12) + state.dark_idx
  162.     marker[6, 6] = bytarr(8, 8) + state.bright_idx
  163.     marker[8, 8] = bytarr(4, 4) + state.dark_idx
  164.     state.marker = marker
  165.  
  166.     marker = bytarr(20, 20) + state.dark_idx
  167.     marker[1:18, 2:17] = bytarr(18, 16) + state.bright_idx
  168.     state.unreach = marker
  169.  
  170.   endif
  171.  
  172.   return, res
  173. end
  174.  
  175.  
  176.  
  177.  
  178.  
  179.  
  180.  
  181. pro CSEL_MVMARK, state, to_index
  182. ; Move the marker and update the current color square.
  183.  
  184.   cur_idx = state.cur_idx
  185.  
  186.   new_pos = to_index ne cur_idx
  187.  
  188.   ; Restore current square
  189.   save_win = !D.WINDOW
  190.   wset, state.spectrum_win
  191.   if (new_pos) then begin
  192.     tv, bytarr(20, 20) + byte(cur_idx), cur_idx
  193.     state.cur_idx = (cur_idx = to_index)
  194.   endif
  195.   tv, state.marker, cur_idx
  196.   wset, save_win
  197.  
  198.  
  199. end
  200.  
  201.  
  202.  
  203.  
  204.  
  205.  
  206.  
  207. function CSEL_EVENT, ev
  208.  
  209.   ; Recover the state of this compound widget
  210.   parent = ev.handler
  211.   stash = WIDGET_INFO(parent, /CHILD)
  212.   WIDGET_CONTROL, stash, GET_UVALUE=state, /NO_COPY
  213.  
  214.  
  215.   case (ev.id) of
  216.  
  217.   state.by_index: begin
  218.     set_slide_idx:
  219.       CSEL_SETSLIDERS, state, 1, state.x, state.y, ev.value
  220.     end
  221.  
  222.   state.column: begin
  223.     CSEL_SETSLIDERS, state, 2, byte(ev.value), state.y, tmp
  224.     end
  225.  
  226.   state.row : begin
  227.     CSEL_SETSLIDERS, state, 3, state.x, byte(ev.value), tmp
  228.     end
  229.  
  230.   state.spectrum: begin
  231.       if (ev.press ne 0) then begin
  232.     tmp = ((319 - ev.y) / 20 ) * 16 + (ev.x / 20)
  233.     CSEL_SETSLIDERS, state, 0, state.x, state.y, tmp
  234.       endif else begin
  235.         WIDGET_CONTROL, stash, SET_UVALUE=state, /NO_COPY
  236.     return, 0        ; Swallow key release events
  237.       endelse
  238.       end
  239.     endcase
  240.  
  241.   value=state.cur_idx
  242.   WIDGET_CONTROL, stash, SET_UVALUE=state, /NO_COPY
  243.   return, {COLORSEL_EVENT, ID: parent, TOP:ev.top, HANDLER:0L, VALUE: value }
  244.  
  245. end
  246.  
  247.  
  248.  
  249.  
  250.  
  251.  
  252.  
  253. pro CSEL_REALIZE, id
  254.  
  255.   ;Retrieve the state information.
  256.   stash = WIDGET_INFO(id, /CHILD)
  257.   WIDGET_CONTROL, stash, GET_UVALUE=state, /NO_COPY
  258.  
  259.  
  260.   ; Initialize everything
  261.   ; What is the spectrum window id?
  262.   WIDGET_CONTROL, state.spectrum, get_value=tmp
  263.   state.spectrum_win=tmp
  264.  
  265.   junk = CSEL_NEW_COLORS(state)
  266.   ; Draw spectrum widgets
  267.   save_win = !D.WINDOW
  268.   wset, state.spectrum_win
  269.   tmp=bytarr(20,20)
  270.   for i = 0, !d.table_size-1 do begin
  271.     tv, tmp, i
  272.     tmp = tmp + 1B
  273.   endfor
  274.  
  275.  
  276.   ; Draw the unreachable squares
  277.   tmp = state.unreach
  278.   for i = !d.table_size, 255 do tv, tmp, i
  279.   WSET, save_win
  280.  
  281.   ; Highlight the current position using the marker
  282.   CSEL_MVMARK, state, state.cur_idx
  283.  
  284.   WIDGET_CONTROL, stash, SET_UVALUE=state, /NO_COPY
  285. end
  286.  
  287.  
  288.  
  289.  
  290.  
  291.  
  292.  
  293. pro CSEL_SET_VALUE, id, value
  294.  
  295.   if (value eq -1) then begin
  296.     CSEL_REALIZE, id
  297.   endif else begin
  298.     ;Retrieve the state information.
  299.     stash = WIDGET_INFO(id, /CHILD)
  300.     WIDGET_CONTROL, stash, GET_UVALUE=state, /NO_COPY
  301.  
  302.     CSEL_SETSLIDERS, state, 0, 0, 0, value
  303.  
  304.     WIDGET_CONTROL, stash, SET_UVALUE=state, /NO_COPY
  305.   endelse
  306.  
  307. end
  308.  
  309.  
  310.  
  311.  
  312.  
  313.  
  314.  
  315. function CSEL_GET_VALUE, id
  316.  
  317.   ;Retrieve the state information.
  318.   stash = WIDGET_INFO(id, /CHILD)
  319.   WIDGET_CONTROL, stash, GET_UVALUE=state, /NO_COPY
  320.  
  321.   ret = state.cur_idx
  322.  
  323.   WIDGET_CONTROL, stash, SET_UVALUE=state, /NO_COPY
  324.   return, ret 
  325. end
  326.  
  327.  
  328.  
  329.  
  330.  
  331.  
  332.  
  333. function CW_COLORSEL, parent, FRAME = frame, UVALUE = uval, $
  334.     XOFFSET=xoff, YOFFSET=yoff
  335.  
  336.  
  337.   state = { by_index:0L, $        ; By index slider widget
  338.         row:0L, $            ; Row slider widget
  339.         column:0L, $        ; Column slider widget
  340.         spectrum:0L, $        ; Spectrum widget 
  341.         first_child:0L, $        ; ID of first child of base.
  342.         x:0L, y:0L, $        ; Current X and Y of marker in spectrum
  343.         cur_idx:0, $        ; Current index
  344.         marker:bytarr(20,20,/nozero), $    ; Byte array used as marker
  345.         unreach:bytarr(20,20,/nozero), $    ; Image for unreachable colors
  346.         spectrum_win:0, $        ; Spectrum draw window index
  347.         bright_idx:-1, dark_idx:-1}    ; Dark and bright colors for marker
  348.  
  349.  
  350.   on_error,2              ;Return to caller if an error occurs
  351.  
  352.   IF NOT (KEYWORD_SET(frame))  THEN frame = 0
  353.   IF NOT (KEYWORD_SET(uval))  THEN uval = 0
  354.   IF NOT (KEYWORD_SET(xoff))  THEN xoff = 0
  355.   IF NOT (KEYWORD_SET(yoff))  THEN yoff = 0
  356.  
  357.   version = WIDGET_INFO(/VERSION)
  358.   newer_motif = (version.style eq 'Motif') and (version.release ne '1.0')
  359.  
  360.   ; Create widgets
  361.   base = WIDGET_BASE(parent,  frame=frame, uvalue=uval, $
  362.     EVENT_FUNC='CSEL_EVENT', FUNC_GET_VALUE='CSEL_GET_VALUE', $
  363.     PRO_SET_VALUE='CSEL_SET_VALUE', NOTIFY_REALIZE='CSEL_REALIZE', $
  364.     XOFFSET=xoff, YOFFSET=yoff)
  365.   if (newer_motif) then begin
  366.         state.row = WIDGET_SLIDER(base, min=15, max=0, xoff = 325, $
  367.         yoff= 75, /vert, val=0, title='Row', ysize=320)
  368.   endif else begin
  369.         state.row = WIDGET_SLIDER(base, min=15, max=0, xoff = 325, $
  370.         yoff= 75, /vert, val=0, title='Row', ysize=320, xsize=75)
  371.   endelse
  372.   state.column = WIDGET_SLIDER(base, max=15, title='Column', $
  373.     xsize=320, yoff=400)
  374.   state.spectrum=WIDGET_DRAW(base, xsize=320, ysize=320, /frame, /button, $
  375.     yoff=75)
  376.   state.by_index = WIDGET_SLIDER(base, max=!d.table_size-1, $
  377.     title = 'By Index', xsize=320)
  378.  
  379.  
  380.   state.cur_idx = 0
  381.   state.x = 0
  382.   state.y = 0
  383.  
  384.   ; Stash the state
  385.   WIDGET_CONTROL, WIDGET_INFO(base, /CHILD), SET_UVALUE=state, /NO_COPY
  386.  
  387.   return, base
  388. end
  389.